package com.hy.socket.handler;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.json.JSONUtil;
import com.hy.socket.dto.Message;
import com.hy.util.SpringUtils;
import com.hy.util.WebsocketUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.server.standard.SpringConfigurator;

import javax.annotation.Resource;
import javax.servlet.ServletContext;
import javax.websocket.*;
import javax.websocket.server.HandshakeRequest;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import javax.websocket.server.ServerEndpointConfig;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

@ServerEndpoint(value = "/chat/{userId}")
@Component
public class ChatSocketHandler {

	private StringRedisTemplate stringRedisTemplate = SpringUtils.getBean(StringRedisTemplate.class);;

	public static void connectOK(Long userId) {
		final Message message = new Message("connect", null, null, "CONNECT_SUCCESS", LocalDateTime.now());
		WebsocketUtil.sendMessage(userId, message);
	}

	//前端请求时一个websocket时
	@OnOpen
	public void onOpen(Session session, @PathParam("userId") Long userId) {
		WebsocketUtil.addSession(userId, session);
		connectOK(userId);
		System.out.println("【websocket消息】有新的连接,连接id"+userId);

		// 通知有共同好友的在线用户更新
		// 通过redis

		// 查看是否有没有接收的消息
		String key = "chat.message." + userId;
		final List<String> list = stringRedisTemplate.opsForList().range(key, 0, -1);
		if (list == null || list.isEmpty()) {
			return;
		}

		final List<Message> result = list.stream()
				.map(item -> JSONUtil.toBean(item, Message.class))
				.collect(Collectors.toList());
		System.out.println("result = " + result);
//		for (String msg : list) {
//		final Message message = new Message("list-msg", null, userId, list, LocalDateTime.now());
		WebsocketUtil.sendMessage(userId, new Message("list-msg", null, userId, result, LocalDateTime.now()));
//		}
		stringRedisTemplate.delete(key);

	}

	//前端关闭时一个websocket时
	@OnClose
	public void onClose(@PathParam("userId") Long userId) {
		WebsocketUtil.removeSession(userId);
//		webSocketMap.remove(userId);
		System.out.println("【websocket消息】连接断开,总数:"+ WebsocketUtil.size());
		// 通知下线
	}

	//前端向后端发送消息
	@OnMessage
	public void onMessage(String data) {
		System.err.println("message = " + data);
		final Message message = JSONUtil.toBean(data, Message.class);
		message.setTime(LocalDateTime.now());
		if ("ping".equals(message.getType())) {
			message.setType("pong");
			WebsocketUtil.sendMessage(message.getFrom(), message);
			return;
		}
//		final Message send = new Message("message", message.getFrom(), message.getTo(), message.getData());

		// 判断接收方是否登录
		final String json = JSONUtil.toJsonStr(message);
		System.out.println(message);
		if (WebsocketUtil.getSession(message.getTo()) == null) {
			// TODO 不在线 保存到消息队列 or 缓存
			String key = "chat.message." + message.getTo();
			stringRedisTemplate.opsForList().rightPush(key, json);
			stringRedisTemplate.persist(key);
			return;
		}
		WebsocketUtil.sendMessage(message.getTo(), json);
	}
}

